<?php
namespace api\modules\v1\models;

use Yii;
use api\components\ApiModel;
use common\models\ARCoinType;
use common\models\ARCurrencyType;
use common\models\ARAssets;
use common\models\ARCoinTake;
use common\models\ARAddressout;
use common\models\ARCoinRecord;
use yii\helpers\ArrayHelper;

/**
 * 代币模型
 * @author CGA
 */
class Coin extends ApiModel
{
    const SCENARIO_TYPE_ADD = 'type_add';
    const SCENARIO_GET_AMOUNT = 'get_amount';
    const SCENARIO_WITHDRAWALS = 'withdrawals';
    const SCENARIO_GET_HISTORY = 'get_history';

    public $coin_name;
    public $coin;
    public $amount;
    public $toaddress;
    public $category;
    public $start;
    public $end;
    public $page;
    public $size;

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'coin_name' => '币种名称',
            'coin'      => '币种',
            'amount'    => '数额',
            'toaddress' => '提币地址',
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        return [
            self::SCENARIO_TYPE_ADD    => ['coin_name'],
            self::SCENARIO_GET_AMOUNT  => ['coin'],
            self::SCENARIO_WITHDRAWALS => ['coin', 'amount', 'toaddress'],
            self::SCENARIO_GET_HISTORY => ['coin', 'category', 'start', 'end', 'page', 'size'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['coin_name'], 'trim'],
            [['coin'], 'required', 'on' => [self::SCENARIO_GET_AMOUNT, self::SCENARIO_WITHDRAWALS]],
            [['coin_name', 'amount', 'toaddress'], 'required'],
            ['coin', 'in', 'range' => ARCoinType::find()->where(['status' => ARCoinType::STATUS_ACTIVE])->select('id')->asArray()->column()],
            ['page', 'default', 'value' => 1],
            ['size', 'default', 'value' => 10],
        ];
    }

    /**
     * 获取可用币种
     */

    public function getCoinAmount()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $assets = ARAssets::find()->where(['uid' => Yii::$app->user->id, 'coin' => $this->coin])->one();
        if ($assets) {
            return ['amount' => $assets->amount];
        }
        return ['amount' => 0];
    }

    /**
     * 添加虚拟币币种
     */
    public function coinAdd()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $newCoin = strtoupper($this->coin_name);
        $row = ARCoinType::findOne(['name' => $newCoin]);
        if ($row) {
            self::throwError('400001');
        } else {
            $model = new ARCoinType();
            $model->name = $newCoin;
            if (!$model->save()) {
                self::getErrorMessge($model);
            } else {
                return [
                    'id'   => $model->id,
                    'name' => $model->name,
                ];
            }
        }
    }

    /**
     * 虚拟币列表
     */
    public static function getCoinList()
    {
        $result = ARCoinType::find()->select(['id', 'name'])->where(['status' => ARCoinType::STATUS_ACTIVE])->asArray()->all();
        return $result;
    }

    /**
     * 添加法币币种
     */
    public function currencyAdd()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $newCoin = strtoupper($this->coin_name);
        $row = ARCurrencyType::findOne(['name' => $newCoin]);
        if ($row) {
            self::throwError('400001');
        } else {
            $model = new ARCurrencyType();
            $model->name = $newCoin;
            if (!$model->save()) {
                self::getErrorMessge($model);
            } else {
                return [
                    'id'   => $model->id,
                    'name' => $model->name,
                ];
            }
        }
    }

    /**
     * 法币列表
     */
    public static function getCurrencyList()
    {
        $result = ARCurrencyType::find()->select(['id', 'name'])->where(['status' => ARCurrencyType::STATUS_ACTIVE])->asArray()->all();
        return $result;
    }

    /**
     * 更新平台手续费收益
     */
    public static function updatePlatformProfit($order)
    {
        $coin = ARCoinType::findOne([$order->coin]);
        $scale = Yii::$app->params['scale'];
        $profit = bcadd(sprintf("%.{$scale}f", $coin->profit), sprintf("%.{$scale}f", $order->platform_charge), $scale);
        $total = bcadd(sprintf("%.{$scale}f", $coin->total), sprintf("%.{$scale}f", $order->platform_charge), $scale);
        $coin->profit = $profit;
        $coin->total = $total;
        if (!$coin->update()) {
            self::getErrorMessge($coin);
        }
        return true;
    }

    /**
     * 提款
     */
    public function coinWithdrawal()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $uid = Yii::$app->user->id;
        $addrInfo = ARAddressout::findOne(['id' => $this->toaddress, 'uid' => $uid, 'coin' => $this->coin]);
        if (!$addrInfo) {
            self::throwError('600001');
        }
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // list($walletFlag,$result) = CoinWallet::coinTakeOut($addrInfo->address,);
            $flag = Assets::withdrawals($uid, $this->coin, $this->amount);
            if ($flag) {
                // $takeRecord = new ARCoinTake();
                // $takeRecord-
                return true;
            }
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 获取钱包历史
     */
    public function getCoinHistory()
    {
        if (!$this->validate()) {
            self::getErrorMessge($this);
        }
        $uid = $uid = Yii::$app->user->id;
        $model = ARCoinRecord::find()->with('coinType')->where(['uid' => $uid]);
        if ($this->coin) {
            $model->andWhere(['coin' => $this->coin]);
        }
        if ($this->category) {
            $model->andWhere(['category' => $this->category]);
        }
        if ($this->start) {
            $model->andWhere(['>', 'created_at', $this->start]);
        }
        if ($this->end) {
            $model->andWhere(['<', 'created_at', $this->end]);
        }
        $count = $model->count();
        $result = $model->limit($this->size)->offset($this->size * ($this->page - 1))->orderBy(['created_at' => SORT_DESC])->all();
        if ($result) {
            $rows = ArrayHelper::toArray($result, [
                ARCoinRecord::className() => [
                    'id',
                    'type',
                    'category'     => function ($row) {
                        return ARCoinRecord::getCategoryLabel($row->category);
                    },
                    'status'       => function ($row) {
                        return ARCoinRecord::getStatusLabel($row->status);
                    },
                    'coin'         => function ($row) {
                        return $row->coinType->name;
                    },
                    'amount'       => function ($row) {
                        return sprintf("%.4f", $row->amount);
                    },
                    'created_time' => function ($row) {
                        return Yii::$app->formatter->asDatetime($row->created_at);
                    },
                    'updated_time' => function ($row) {
                        return Yii::$app->formatter->asDatetime($row->updated_at);
                    },
                ],
            ]);
        } else {
            $rows = [];
        }

        return ['count' => $count, 'rows' => $rows];

    }

    /**
     * 获取收支类型
     */
    public static function getCategorys()
    {
        $result = ARCoinRecord::getCategoryLabel();
        foreach ($result as $key => $value) {
            $row = [
                'id'   => $key,
                'name' => $value,
            ];
            $data[] = $row;
        }
        return $data;
    }
}
